# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: daniel

from scapy.all import *
import re
import sys
import numpy as np
import json
import pandas as pd

# parse pcap data into json format
file_name  = sys.argv[1]
client     = '10.81.1.122'
server     = '10.21.1.29'
requests   = []
for (pkt_data, pkt_metadata,) in RawPcapReader(file_name):
    ether_pkt = Ether(pkt_data)
    if 'type' not in ether_pkt.fields:
        continue
    if ether_pkt.type != 0x0800:
        continue
    ip_pkt    = ether_pkt[IP]
    if ip_pkt.proto != 6:
        continue
    tcp_pkt   = ip_pkt[TCP]
    if ip_pkt.dst != server:
        continue
    if tcp_pkt.dport != 8080:
        continue
    tcp_payload_len = ip_pkt.len - (ip_pkt.ihl * 4) - (tcp_pkt.dataofs * 4)
    if tcp_payload_len == 0:
        continue
    ts   = (pkt_metadata.tshigh << 32) | pkt_metadata.tslow
    pl   = bytes(tcp_pkt.payload).decode()
    reqs = re.findall('GET \/\?session=(\d+)&index=(\d+)&interval=(\d+)', pl)
    for req in reqs:
        requests.append({'session': req[0], 'index': req[1], 'interval': req[2], 'ts': ts })

# read json file
j  = json.dumps(requests)
df = pd.read_json(j, orient='records')

intervals = [row['interval'] for _, row in df.iterrows()]
intervals = np.unique(intervals)

print("%20s : %20s (ms)" % ("Category(Interval)", "Time Delta(ts2 - ts1)"))
for interval in intervals:
    # session1
    s1  = [row for _, row in df.iterrows() if row['interval'] == interval and row['session'] == 1]
    s1  = sorted(s1, key=lambda x: x['index'])
    s11 = []
    idx = 0
    for s0 in s1:
        if idx != s0['index']:
            continue
        s11.append(s0)
        idx += 1
    ts1 = np.array([each['ts'] for each in s11])

    # session2
    s2  = [row for _, row in df.iterrows() if row['interval'] == interval and row['session'] == 2]
    s2  = sorted(s2, key=lambda x: x['index'])
    s22 = []
    idx = 0
    for s0 in s2:
        if idx != s0['index']:
            continue
        s22.append(s0)
        idx += 1
    ts2 = np.array([each['ts'] for each in s22])

    # mean
    print("%20s : %20s (ms)" % (interval, np.median(ts2 - ts1) / 1000000))
